/***************************************************************************
 *   Copyright (C) 2008 by Chris Vickery   *
 *   chrisinajar@gmail.com   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
#include "mainapplication.h"

#include <QTime>
#include <QTimer>
#include <QDebug>
#include <QApplication>

#include <Ogre.h>

#define FRAME_LIMIT 15
#define FPS_INTERVAL 10000

MainApplication::MainApplication(QObject *parent)
		: QObject(parent),
		timer(0, 0, 0, 0),
		fpsCounter(0)
{
	ogre = new Ogre::Root();
	ogre->addFrameListener(this);
	///@todo: Make Cross Platform: Windows, Mac OS X
	ogre->loadPlugin("/usr/lib/OGRE/RenderSystem_GL.so");
	Ogre::RenderSystemList* rsl = ogre->getAvailableRenderers();
	Q_ASSERT(!rsl->empty());   // we need at least one renderer to do anything useful
	Ogre::RenderSystem* rs = rsl->at(0);
	ogre->setRenderSystem(rs);
	rs->setConfigOption("Full Screen", "No");
	rs->setConfigOption("Video Mode", "1024 x 768 @ 32-bit colour");
	ogre->initialise(true, "Operation Astronaut");

	Ogre::TextureManager::getSingleton().setDefaultNumMipmaps(5);
	Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
	sceneMgr = ogre->createSceneManager(Ogre::ST_GENERIC, "Default SceneManager");
	sceneMgr->setAmbientLight(Ogre::ColourValue(1.0f, 1.0f, 1.0f));

	camera = sceneMgr->createCamera("Camera");
	camera->setPosition(0.0f, 0.0f, 150.0f);
	camera->lookAt(0.0f, 0.0f, 0.0f);
	camera->setNearClipDistance(1);

	window = ogre->getAutoCreatedWindow();
	window->addViewport(camera);

	Ogre::ResourceGroupManager::getSingleton().addResourceLocation("./", "FileSystem");
	Ogre::MaterialManager::getSingleton().load("General/SOLID", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
	Ogre::MeshManager::getSingleton().load("Cube.mesh", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
	QTimer* t = new QTimer(this);
	t->setInterval(0);
	connect(t, SIGNAL(timeout()), this, SLOT(iterate()));

	QTimer* fpst = new QTimer(this);
	fpst->setInterval(FPS_INTERVAL);
	connect(fpst, SIGNAL(timeout()), this, SLOT(showFps()));

	// Create the objects
	Ogre::Entity* ship = sceneMgr->createEntity("ship", "Cube.mesh");
	Ogre::SceneNode* shipNode = sceneMgr->getRootSceneNode()->createChildSceneNode("ShipNode", Ogre::Vector3(0.0f, 0.0f, 0.0f));
	shipNode->setPosition(2, 5, 0);
	shipNode->attachObject(ship);

	ship->setVisible(true);
	/*
	Ogre::Light* light = sceneMgr->createLight("MainLight");
	light->setType(Ogre::Light::LT_POINT);
	light->setSpecularColour(100, 100, 100);
	light->setPosition(0, 0, 0);
	*/

	qDebug() << "Initialized!";

	timer.start();
	t->start();
	fpst->start();
	emit started();
	spaceShip = new GraphicalObject(this);
}

void MainApplication::iterate()
{
	int elapsed = timer.elapsed();
	if (elapsed < FRAME_LIMIT)
	{
		usleep((FRAME_LIMIT - elapsed)*1000);
		elapsed = FRAME_LIMIT;
	}
	spaceShip->setDirection(fpsCounter);
	fpsCounter++;
	timer.restart();
	if (!ogre->renderOneFrame())
		qApp->quit();
	Ogre::WindowEventUtilities::messagePump();
}

void MainApplication::showFps()
{
	qDebug() << "FPS:" << (fpsCounter*1000 / FPS_INTERVAL);
	fpsCounter = 0;
}

MainApplication::~MainApplication()
{
}


